package com.ruoyi.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.utils.GenerateRandomCode;
import com.ruoyi.common.utils.sqResponseStatus;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.RedisKey;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.domain.Customer;
import com.ruoyi.domain.dto.CustomerDto;
import com.ruoyi.domain.vo.CustomerVo;
import com.ruoyi.service.ICustomerService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 客户表 前端控制器
 * </p>
 *
 * @author 林颖
 * @since 2024-01-23
 */
@RestController
@RequestMapping("/customers")
public class CustomerController {
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private ICustomerService customerService;

    /**
     * 获取验证码
     * @param customer 客户信息
     * @return
     */
    @Anonymous
    @GetMapping("/getCode")
    public AjaxResult getCode(Customer customer){
        // 设置序列化器
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(new StringRedisSerializer());
        try {
            String key = RedisKey.CLIENT_SMS_CODE_KEY+customer.getPhoneNumber();

            //1.在发送短信的手机号码前拼接上"CLIENT_SMS_CODE:"作为key，查询redis缓存中是否有当前手机号码的验证码，若有，则踢回
            String getKey = redisTemplate.opsForValue().get(key);
            if (getKey != null){
                return AjaxResult.error(sqResponseStatus.CODE_EXIST.getStatusCode(),"当前验证码还在有效期，请勿重复获取！");
            }

            //2.生成验证码，并存入缓存中，存储格式为：(CLIENT_SMS_CODE:号码,验证码)

            String code = GenerateRandomCode.getCode(4);
            redisTemplate.opsForValue().set(key,code,60, TimeUnit.SECONDS);//存入缓存，并设置验证码的有效期限为60秒

            //3.接入短信接口，然后根据当前手机号码发送短信通知
            logger.info("获取的验证码为：====> {}",code);//手动打印，方便调试。
            // todo 未接入短信接口，调试阶段给前台响应验证码信息，后续删除!
            return AjaxResult.success("获取验证码成功!",code);
        } catch (Exception e) {
            logger.error(e.getMessage());
            return AjaxResult.error(sqResponseStatus.ERROR.getStatusCode(),"获取验证码异常！");
        }
    }

    @Anonymous
    @GetMapping("/testMp")
    public AjaxResult getCustomer(){
        List<Customer> list = customerService.list();
        return AjaxResult.success(list);
    }


    /**
     * 登录
     * @param customer 登录的用户信息
     * @return
     */
    @Anonymous
    @PostMapping("/login")
    public AjaxResult login(@RequestBody CustomerVo customer){
        // 设置序列化器
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(new StringRedisSerializer());
        //1.先根据传入的号码，查询缓存中是否有验证码,若没有则踢回
        //2.校验传入的验证码和缓存中的验证码是否相等，若不相等则踢回
        String getCode = redisTemplate.opsForValue().get(RedisKey.CLIENT_SMS_CODE_KEY+customer.getPhoneNumber());
        if (getCode == null || !getCode.equals(customer.getCode())){
            return AjaxResult.error(sqResponseStatus.CODE_ERROR.getStatusCode(),"您输入的验证码错误或已过期!");
        }

        //3.查询customer表，有无当前号码，若没有则表示是新用户，为其进行注册操作，然后回显信息。
        LambdaQueryWrapper<Customer> lqw = new LambdaQueryWrapper<>();
        lqw.eq(Customer::getPhoneNumber,customer.getPhoneNumber());
        Customer customerInfo = customerService.getOne(lqw);

        if (customerInfo == null){
            try {
                //新用户，进行customer注册落表操作
                String uuid = IdUtils.randomUUID();
                customer.setCustomerId(uuid);
                customerService.save(customer);
                //落表后 重新赋值用户信息
                customerInfo = customerService.getOne(lqw);
            } catch (Exception e) {
                logger.error(e.getMessage());
                return AjaxResult.error(sqResponseStatus.ERROR.getStatusCode(),"程序异常: "+e.getMessage());
            }
        }

        String tokenKey = RedisKey.CLIENT_KEY+customer.getPhoneNumber();
        //token=CLIENT:当前用户账号:uuid
        String uuid = RandomUtil.simpleUUID();
        String token = RedisKey.CLIENT_KEY + customer.getPhoneNumber() +":" + uuid;
        redisTemplate.opsForValue().set(tokenKey,token,1,TimeUnit.HOURS);//将登录token信息存入缓存中

        //设置响应给前台的数据：包含登录用户信息和token
        CustomerDto customerResult = new CustomerDto();
        BeanUtil.copyProperties(customerInfo,customerResult);
        customerResult.setToken(token);

        return AjaxResult.success("登录成功！",customerResult);
    }

}

